package com.mine.yyb.modules.sys.service.impl;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mine.yyb.common.consts.YybConstants;
import com.mine.yyb.common.utils.exception.MineErrorCode;
import com.mine.yyb.common.utils.exception.MineException;
import com.mine.yyb.common.utils.jdbc.MinePagination;
import com.mine.yyb.common.utils.secret.MineSecretManager;
import com.mine.yyb.modules.sys.bo.UserBO;
import com.mine.yyb.modules.sys.dao.IUserDao;
import com.mine.yyb.modules.sys.enums.UserRoleEnum;
import com.mine.yyb.modules.sys.enums.UserStatusEnum;
import com.mine.yyb.modules.sys.service.IUserService;
import com.mine.yyb.modules.sys.utils.CmsMail;
import com.mine.yyb.modules.sys.vo.UserVO;

@Service(value = "iUserService")
public class UserServiceImpl implements IUserService
{
    private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    
    @Autowired
    private IUserDao iUserDao;
    
    @Autowired
    private CmsMail cmsMail;
    
    @Override
    public UserVO registerUser(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setUsername(userBO.getUsername());
            userVO.setPassword(userBO.getPassword());
            String innerID = UUID.randomUUID().toString().replaceAll("-", "");
            userVO.setInnerID(innerID);
            userVO.setParentInnerID(userBO.getParentInnerID());
            userVO.setStatus(UserStatusEnum.USER_NONACTIVATED_STATUS.getStatus());
            userVO.setEmail(userBO.getEmail());
            userVO.setQq(userBO.getQq());
            
            int result = iUserDao.save(userVO);
            
            if (result > 0)
            {
                doSendActiveEmail(userVO);
            }
            
            return result > 0 ? userVO : null;
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    @Override
    public void reSendEmail(UserBO userBO)
        throws MineException
    {
        try
        {
            UserVO userVO = new UserVO();
            userVO.setInnerID(userBO.getInnerID());
            userVO.setEmail(userBO.getEmail());
            userVO.setUsername(userBO.getUsername());
            
            doSendActiveEmail(userVO);
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    @Override
    public String pwdRecovery(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setEmail(userBO.getEmail());
            Random random = new Random();
            int x = random.nextInt(899999);
            x = x + 100000;
            userVO.setPassword(MineSecretManager.getInstance().encryptMD5(String.valueOf(x)));
            
            int result = iUserDao.update(userVO);
            
            if (result > 0)
            {
                userVO.setPassword(String.valueOf(x));
                doSendRecoveryEmail(userVO);
            }
            
            return result > 0 ? MineErrorCode.SUCCESS.name() : MineErrorCode.ERROR_INTERNAL.name();
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }

    /** 
     * <pre>
     * <一句话功能简述>
     * 
     * 发送邮件
     * 
     * <功能详细描述>
     * </pre>
     *
     * @author  xuganhua
     * @version  [版本号, 2016年1月21日]
     * @param request
     * @param userBO
     * @return
     * @see [类、类#方法、类#成员]
     */
    private void doSendActiveEmail(UserVO userVO)
        throws Exception
    {
        Map<String, String> params = new HashMap<String, String>();
        params.put("innerID", URLDecoder.decode(userVO.getInnerID(), YybConstants.ENCODE_UTF8));
        params.put("username", URLDecoder.decode(userVO.getUsername(), YybConstants.ENCODE_UTF8));
        // 发送邮件
        cmsMail.sendActiveMail(userVO.getEmail(),
            URLDecoder.decode(userVO.getEmail(), YybConstants.ENCODE_UTF8),
            params);
    }
    
    /** 
     * <pre>
     * <一句话功能简述>
     * 
     * 发送密码重置邮件
     * 
     * <功能详细描述>
     * </pre>
     *
     * @author  xuganhua
     * @version  [版本号, 2016年2月17日]
     * @param userVO
     * @throws Exception
     * @see [类、类#方法、类#成员]
     */
    private void doSendRecoveryEmail(UserVO userVO)
        throws Exception
    {
        Map<String, String> params = new HashMap<String, String>();
        params.put("password", URLDecoder.decode(userVO.getPassword(), YybConstants.ENCODE_UTF8));
        // 发送邮件
        cmsMail.sendRecoveryMail(userVO.getEmail(),
            URLDecoder.decode(userVO.getEmail(), YybConstants.ENCODE_UTF8),
            params);
    }
    
    @Override
    public String activateUser(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setInnerID(userBO.getInnerID());
            userVO.setStatus(UserStatusEnum.USER_ACTIVATED_STATUS.getStatus());
            
            int result = iUserDao.update(userVO);
            return result > 0 ? MineErrorCode.SUCCESS.name() : MineErrorCode.ERROR_INTERNAL.name();
            
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    @Override
    public String deleteUser(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setInnerID(userBO.getInnerID());
            
            int result = iUserDao.delete(userVO);
            return result > 0 ? MineErrorCode.SUCCESS.name() : MineErrorCode.ERROR_INTERNAL.name();
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }

    @Override
    public boolean isEmailExist(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setEmail(userBO.getEmail());
            userVO.setRole(UserRoleEnum.USER_NORMAL_ROLE.getRole());
            
            UserVO result = iUserDao.queryUser(userVO);
            if (result == null)
            {
                return false;
            }
            return true;
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    @Override
    public boolean isUsernameExist(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setUsername(userBO.getUsername());
            userVO.setRole(UserRoleEnum.USER_NORMAL_ROLE.getRole());
            
            UserVO result = iUserDao.queryUser(userVO);
            if (result == null)
            {
                return false;
            }
            return true;
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    @Override
    public UserVO queryTheUser(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setUsername(userBO.getUsername());
            userVO.setPassword(userBO.getPassword());
            userVO.setStatus(UserStatusEnum.USER_ACTIVATED_STATUS.getStatus());
            userVO.setRole(userBO.getRole());
            
            UserVO result = iUserDao.queryUser(userVO);
            if (result == null) // 可以通过邮箱或者账号进行登录
            {
                userVO.setUsername(null);
                userVO.setEmail(userBO.getUsername());
                userVO.setPassword(userBO.getPassword());
                userVO.setStatus(UserStatusEnum.USER_ACTIVATED_STATUS.getStatus());
                userVO.setRole(userBO.getRole());
                result = iUserDao.queryUser(userVO);
                
                if(result == null) 
                {
                    return null;
                }
            }
            return result;
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    public MinePagination<UserVO> queryUserList(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setCreateDate(userBO.getCreateDate());
            userVO.setUsername(userBO.getUsername());
            userVO.setEmail(userBO.getEmail());
            
            return iUserDao.queryUser(userVO, userBO.getsEcho(), userBO.getiDisplayStart(), userBO.getiDisplayLength());
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    @Override
    public String changeUserPwd(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setInnerID(userBO.getInnerID());
            userVO.setPassword(userBO.getNewPwd());
            
            int result = iUserDao.update(userVO);
            
            return result > 0 ? MineErrorCode.SUCCESS.name() : MineErrorCode.ERROR_INTERNAL.name();
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    @Override
    public String updateUserPay(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setInnerID(userBO.getInnerID());
            userVO.setPayAccount(userBO.getPayAccount());
            userVO.setName(userBO.getName());
            
            int result = iUserDao.updateUserPay(userVO);
            
            return result > 0 ? MineErrorCode.SUCCESS.name() : MineErrorCode.ERROR_INTERNAL.name();
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    @Override
    public String updateUserQQ(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setInnerID(userBO.getInnerID());
            userVO.setQq(userBO.getQq());
            
            int result = iUserDao.updateUserQQ(userVO);
            
            return result > 0 ? MineErrorCode.SUCCESS.name() : MineErrorCode.ERROR_INTERNAL.name();
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }

    @Override
    public boolean isPayAccountExist(UserBO userBO)
        throws MineException
    {
        try
        {
            logger.info(userBO.toString());
            
            UserVO userVO = new UserVO();
            userVO.setPayAccount(userBO.getPayAccount());
            userVO.setRole(UserRoleEnum.USER_NORMAL_ROLE.getRole());
            
            UserVO result = iUserDao.queryUser(userVO);
            if (result == null)
            {
                return false;
            }
            return true;
        }
        catch (MineException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new MineException(MineErrorCode.ERROR_INTERNAL, e);
        }
    }
    
    
}
